//
//  PMBody.h
//  PezMonkey
//
//  Created by Spence DiNicolantonio on 10/28/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "PMCore.h"
#import "PMBodyDelegate.h"


@interface PMBody : NSObject {
@protected
	// Chipmunk rigid body reference
	cpBody *body;
	
@private
	// User defined data pointer. This pointer should typically be used to 
	// reference the object that the rigid body represents within the engine.
	id data;
	
	// delegate object. Used to provide delegation of velocity/position updating
	NSObject<PMBodyDelegate> *delegate;
}

@property (nonatomic, retain) id data;
@property (nonatomic, assign) NSObject<PMBodyDelegate> *delegate;;

// Property definitions of getters/setters for data members stored by backend 
// Chipmunk structure. These properties are not synthesized, because their 
// implementations are given explicitly.
@property (assign, readonly) cpBody *cpBody;
@property (assign) PMFloat mass;
@property (assign, readonly) PMFloat massInverse;
@property (assign) PMFloat moment;
@property (assign, readonly) PMFloat momentInverse;
@property (assign) PMVect position;
@property (assign) PMVect velocity;
@property (assign) PMFloat terminalVelocity;
@property (assign) PMVect force;
@property (assign) PMFloat angle;
@property (assign, readonly) PMVect rotationVector;
@property (assign) PMFloat angularVelocity;
@property (assign) PMFloat terminalAngularVelocity;
@property (assign) PMFloat torque;

#pragma mark -
#pragma mark Init
- (id)initWithMass:(PMFloat)mass moment:(PMFloat)moment;

#pragma mark Convenience
+ (PMBody *)staticBody;
+ (PMBody *)bodyWithMass:(PMFloat)mass moment:(PMFloat)moment;


#pragma mark -
#pragma mark Force Application

- (void)applyImpulse:(PMVect)impulse;
- (void)applyImpulse:(PMVect)impulse atRelativeOffset:(PMVect)offset;
- (void)applyForce:(PMVect)force;
- (void)applyForce:(PMVect)force atRelativeOffset:(PMVect)offset;
- (void)applyTorque:(PMFloat)torque;
- (void)resetForces;


#pragma mark -
#pragma mark Update
- (void)updateVelocityWithTime:(NSTimeInterval)time gravity:(PMVect)gravity damping:(PMFloat)damping;
- (void)updatePositionWithTime:(NSTimeInterval)time;


#pragma mark -
#pragma mark Other Methods
- (void)slewToPoint:(PMVect)point inTime:(PMFloat)time;
- (PMVect)convertPointFromLocal:(PMVect)point;
- (PMVect)convertPointToLocal:(PMVect)point;
- (PMVect)convertPointFromWorld:(PMVect)point;
- (PMVect)convertPointToWorld:(PMVect)point;

@end


#pragma mark -
#pragma mark Functions
static void PMBodyChipmunkVelocityFunction(cpBody *bodyRef, cpVect gravity, cpFloat damping, cpFloat dt);
static void PMBodyChipmunkPositionFunction(cpBody *bodyRef, cpFloat dt);

